package com.r2coding.article.aop;

import com.r2coding.article.dao.ArticleDao;
import com.r2coding.article.entity.ArticleEntity;
import com.r2coding.common.constant.Constant;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author:98k灬
 * @since:2022/06/06 12:57
 **/
@Slf4j
@Aspect
@Component
public class UpdateArticleViewAspect {
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    ArticleDao articleDao;

    @Pointcut("@annotation(com.r2coding.article.annotation.UpdateArticleView)")
    public void pointcut() {}

    @After("pointcut()")
    public synchronized void doAfter(JoinPoint joinPoint) {
        try {
            Object[] args = joinPoint.getArgs();
            Integer articleId = (Integer)args[0];
            log.info("更新文章浏览量: {}", articleId);
            // 先判断redis中是否有该用户阅读过该文章
            // 获取用户id
            SecurityContext context = SecurityContextHolder.getContext();
            Authentication authentication = context.getAuthentication();
            OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails)authentication.getDetails();
            Map<String, Object> map = (Map<String, Object>)details.getDecodedDetails();
            Map<String, Object> userInfo = (Map<String, Object>)map.get("userInfo");
            Integer userId = (Integer)userInfo.get("userId");
            String key = Constant.ARTICLE_VIEW_PREFIX + String.valueOf(userId) + "_" + String.valueOf(articleId);
            if (!stringRedisTemplate.hasKey(key)) {
                ArticleEntity article = articleDao.selectById(articleId);
                article.setViews(article.getViews() + 1);
                article.setUpdateTime(new Date());
                articleDao.updateById(article);
                // 防刷阅读量  限制2小时
                stringRedisTemplate.opsForValue().set(key, String.valueOf(articleId), 120, TimeUnit.MINUTES);
            }
        } catch(Exception e) {
            log.error(e.getMessage());
        }
    }
}
